package com.open.web.config;

import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author: codex
 * @Date: 2024/5/6 下午5:29
 * @Version: V1.0
 * @description: desc:
 */


@EnableConfigurationProperties({ServerProperties.class, WebMvcProperties.class})
@Configuration
public class SystemWebConfig {

    @ConditionalOnClass(CorsFilter.class)
    @Configuration
    static class DependenceCorsFilterConfig {
        @Bean
        @ConditionalOnMissingBean
        public CorsFilter corsFilter(CommonProperties commonProperties) {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration configuration = new CorsConfiguration();
            configuration.setAllowedOriginPatterns(commonProperties.getCorsAllowedOrigins());
            configuration.addAllowedHeader("*");
            configuration.addAllowedMethod("*");
            configuration.setAllowCredentials(true);
            configuration.addExposedHeader("Authorization");
            configuration.addExposedHeader("UserToken");
            configuration.addExposedHeader("Content-Disposition");
            configuration.setMaxAge(1800L);
            source.registerCorsConfiguration("/**", configuration);
            return new CorsFilter(source);
        }
    }


    @ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
    @Configuration
    static class DependenceJacksonConfig {
        @Bean
        @ConditionalOnMissingBean
        public Jackson2ObjectMapperBuilderCustomizer customizer(CommonProperties commonProperties) {
            return builder -> {
                builder.serializerByType(LocalDateTime.class,
                        new LocalDateTimeSerializer(DateTimeFormatter
                                .ofPattern(commonProperties.getDateTimePattern())));
                builder.deserializerByType(LocalDateTime.class,
                        new LocalDateTimeDeserializer(DateTimeFormatter
                                .ofPattern(commonProperties.getDateTimePattern())));
                builder.serializerByType(LocalDate.class,
                        new LocalDateSerializer(DateTimeFormatter.ofPattern(commonProperties.getDatePatter())));
                builder.deserializerByType(LocalDate.class,
                        new LocalDateDeserializer(DateTimeFormatter.ofPattern(commonProperties.getDatePatter())));

                // Long 转 String  ，防止前端 Long 精度丢失
                builder.serializerByType(Long.class, ToStringSerializer.instance);
            };
        }
    }
}
